# -*- coding: utf-8 -*-
# !/usr/bin/env python3


""" 
文档说明: 
    1.使用 Airtest 手机群控技术原理说明(多进程控制多台设备抓取), 参考Ref: https://github.com/Python3WebSpider/AirtestTest
    2.更成熟的手机群控技术的商用解决方案(群控技术方案, 对比不同之处), EX：
            掘金网安卓群控系统：https://www.54nb.com/androids/(免费, 功能简单,易于操作)
            侠客科技：https://www.xiake.vip/
            智互云客：http://www.zh-auto.org/
            智云控：http://www.zhiyunkong.com/
            鹰眼：http://ent.mobileanjian.com/
            阿云梯：https://www.ayunti.cn/
            河马云：http://www.longene.com.cn/ (案例参考, 推荐)
            四方来客：http://www.zhiboyk.com/
    3.常见的短信接码平台(因政策原因, 可能需要经常更换)
        番薯云：https://guanfangdiping.com/
        云际云短信：https://yunjisms.xyz/
        接码号：https://jiemahao.com/
        KaKa 接码：http://www.kakasms.com/

@version : 1.0
@author  : Knight
@email   : xxxxxx@mail.com
@Created : 2022-04-10 09:56:27
@Project : Airtest
@Module  : multi_control.py
@Modified: 
"""


from abc import ABCMeta, abstractmethod, abstractproperty
from multiprocessing import Process
from re import T

import adbutils
from airtest.core.api import *
from poco.drivers.android.uiautomation import AndroidUiautomationPoco


class ControllerMeta(object, metaclass=ABCMeta):
    """ 设备控制器 MetaBase"""

    def __init__(self, device_uri, package_name, apk_path, apk_reinstall=False, app_restart=True, **kwargs):
        """ 设备初始化参数"""

        self.device_uri = device_uri
        self.package_name = package_name
        self.apk_path = apk_path
        self.apk_reintall = apk_reinstall
        self.app_restart = app_restart

        # Add other kwargs
        for attr, value in kwargs.items():
            setattr(self, attr, value)

    def connect_device(self, **kwargs):
        """ 链接设备, 可添加设备指纹参数等."""

        self.device = connect_device(self.device_uri, **kwargs)

    def install_app(self):
        """ 设备上是否安装App."""

        if self.device.check_app(self.package_name) and not self.apk_reintall:
            # 无需重新安装 
            return

        self.device.uninstall_app(self.package_name)
        self.device.install_app(self.apk_path)

    def start_app(self):
        """ 是否重启应用"""
        
        if self.app_restart:
            # 关闭应用app, 并重启app
            self.device.stop_app(self.package_name)

        self.device.start_app(self.package_name)

    def init_device(self, **kwargs):
        """ 设备初始化. """

        # 建立连接
        self.connect_device(**kwargs)
        self.poco = AndroidUiautomationPoco(self.device)

        # 获取设备 screen 信息
        self.window_width, self.window_height = self.poco.get_screen_size()
        
        # 安装并启动 app
        self.install_app()
        self.start_app()

    @abstractmethod
    def random_scroll_up(self):
        pass

    @abstractmethod
    def scroll_up(self):
        self.device.swipe((self.window_width * 0.5, self.window_height * 0.8),
                          (self.window_width * 0.5, self.window_height * 0.3), duration=1)
    @abstractmethod
    def parse_cur_page(self):
        pass
    
    @abstractmethod
    def parse_detail_page(self):
        pass  

    @abstractmethod
    def run(self):
        """ 模拟运行, 相关内容."""
        
        for _ in range(10):
            self.scroll_up()


class Controller(metaclass=ControllerMeta):
    """ 重新相关的爬虫抓取流程即可."""

    def stop_crawl_condition(self):
        pass

    def random_scroll_up(self):
        pass

    def generate_uuid(self):
        pass

    def parse_cur_page(self):
        pass
    
    def parse_detail_page(self):
        pass

    def run(self):
        pass


PACKAGE_NAME = 'com.goldze.mvvmhabit'
APK_PATH = 'app-debug.apk'


def run(device_uri):
    controller = Controller(device_uri=device_uri,
                            package_name=PACKAGE_NAME,
                            apk_path=APK_PATH,
                            need_reinstall=False,
                            need_restart=True)
    controller.init_device()
    controller.run()


if __name__ == '__main__':
    
    # 使用本地主机(通过host&port修改连接设备)
    adb = adbutils.AdbClient(host="127.0.0.1", port=5037)
    
    # 收集各设备的处理进程,实现群控技术
    processes = []
    
    for device in adb.devices():
        device_name = device.serial
        device_uri = f'Android:///{device_name}'
        p = Process(target=run, args=[device_uri])
        processes.append(p)
        p.start()

    for p in processes:
        p.join()